﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Apewer.Internals
{

    /// <summary>锁。</summary>
    internal class Locker
    {

        Dictionary<int, Class<object>> _pool = new Dictionary<int, Class<object>>();

        /// <summary>标记指定的字符串。</summary>
        static int Key(string s) => s == null ? 0 : s.GetHashCode();

        /// <summary>清除所有缓存的锁。</summary>
        public void Clear()
        {
            lock (_pool)
            {
                _pool.Clear();
            }
        }

        /// <summary>锁定字符串，执行 Action。</summary>
        public void InLock(string text, Action action)
        {
            if (action == null) return;

            var key = Key(text);
            Class<object> locker;
            lock (_pool)
            {
                if (!_pool.TryGetValue(key, out locker))
                {
                    locker = new Class<object>();
                    _pool.Add(key, locker);
                }
            }

            lock (locker.Value)
            {
                action.Invoke();
            }
        }

        /// <summary>锁定字符串，执行 Func。</summary>
        public T InLock<T>(string text, Func<T> func)
        {
            if (func == null) return default;

            var key = Key(text);
            Class<object> locker;
            lock (_pool)
            {
                if (!_pool.TryGetValue(key, out locker))
                {
                    locker = new Class<object>();
                    _pool.Add(key, locker);
                }
            }

            T result;
            lock (locker.Value)
            {
                result = func.Invoke();
            }
            return result;
        }

    }


}
